using Avalonia.Extensions.Controls;
using Avalonia.ReactiveUI;
using Bilibili.Common;
using Bilibili.Common.Log;
using Bilibili.WebClient;
using PCLUntils;
using PCLUntils.Plantform;
using ReactiveUI;
using Serilog;
using System;
using System.Diagnostics;
using System.IO;
using System.Reactive;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace Avalonia.BiliBili
{
    class Program
    {
        static AppBuilder BuildAvaloniaApp()
        {
            return AppBuilder.Configure<App>()
                          .UsePlatformDetect()
                          .UseReactiveUI()
                          .UseDoveExtensions()
                          .UseChineseInputSupport()
                          .UseSkia()
                          .With(new Win32PlatformOptions())
                          .With(new SkiaOptions())
                          .LogToTrace();
        }
        static void Main(string[] args)
        {
            try
            {
                var name = Assembly.GetExecutingAssembly().GetName().Name;
                using Mutex mutex = new Mutex(true, name, out bool createNew);
                if (createNew)
                {
                    var systemType = PlantformUntils.System;
                    if (systemType == Platforms.Linux || (systemType == Platforms.Windows && !PlantformUntils.IsArmArchitecture))
                    {
                        Current.Instance.Init();
                        BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
                        RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
                        RxApp.DefaultExceptionHandler = Observer.Create<Exception>(OnExceptionHandle);
                        TaskScheduler.UnobservedTaskException += TaskSchedulerUnobservedTaskException;
                    }
                    else
                    {
                        var file = Path.Combine(Extension.GetRoot(true), "!!!!!!!!!!!NOT SUPPORT YOUR SYSTEM!!!!!!!!!!!");
                        if (!File.Exists(file))
                            File.Create(file).Dispose();
                        Environment.Exit(1);
                    }
                }
                else
                    Environment.Exit(1);
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("Something very bad happened", ex);
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
        private static void OnExceptionHandle(Exception ex) =>
            LogManager.Instance.LogError("OnExceptionHandle", ex);
        private static void TaskSchedulerUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
            => LogManager.Instance.LogError("TaskSchedulerUnobservedTaskException", e.Exception);
    }
}